# 定义DMRSType结构体
struct DMRSType
    DMRSCongfigurationType::Float64
    DMRSReferencePoints::String
    NumCDMGroupsWithoutData::Float64
    DMRSdownlinkR16::Bool
    DMRSTypeAPosition::Float64
    DMRSAdditionalPosition::Float64
    DMRSLength::Float64
    CustomSymbolSet::Matrix{Float64}
    DMRSPortSet::Float64
    NIDNSCID::Matrix{Float64}
    NISCID::Float64
    DMRSEnhancedR18::Bool
    CDMGroups::Float64
    DeltaShifts::Float64
    FrequencyWeights::Matrix{Float64}
    TimeWeights::Matrix{Float64}
    DMRSSubcarrierLocations::Matrix{Float64}
    CDMLengths::Matrix{Float64}
end
# 定义PTRSType结构体，包含图中所示的PTRS相关属性
struct PTRSType
    PTRSPortSet::Matrix{Float64}
    TimeDensity::Float64
    FrequencyDensity::Float64
    REOffset::String
end
# 创建一个基础的 PTRSType 实例，根据需求设置初始值
base_ptrs = PTRSType(
    zeros(Float64, 0, 0),
    1,
    2,
    "00"
)
# 定义ReservedConfig结构体
struct nrPDSCHReservedConfigType
    PRBSet::Vector{Float64}
    SymbolSet::Vector{Float64}
    Period::Vector{Float64}
end

# 初始化ReservedConfig实例
reserved_config_instance = nrPDSCHReservedConfigType([], [], [])
# 定义nrCarrierConfig结构体
struct nrCarrierConfig
    NCELLID::Float64
    NSizeGrid::Float64
    NStartGrid::Float64
    NSlot::Float64
    NFrame::Float64
    IntraCellGuardBands::Matrix{Float64}
    SymbolsPerSlot::Float64
    SlotsPerSubframe::Float64
    SlotsPerFrame::Float64
    SubcarrierSpacing::Float64
    CyclicPrefix::String
end

# 创建nrCarrierConfig实例并赋初值
carrier = nrCarrierConfig(
    1,
    51,
    0,
    199,
    0,
    zeros(Float64, 0, 2),
    14,
    2,
    20,
    30,
    "normal"
)
# 定义PDSCHConfig结构体
struct PDSCHConfig
    ReservedRE::Matrix{Float64}
    NID::Matrix{Float64}
    NSizeBWP::Matrix{Float64}
    NStartBWP::Matrix{Float64}
    Modulation::String
    ReservedPRB::nrPDSCHReservedConfigType
    PRBSetType::String
    VRBToPRBInterleaving::Bool
    VRBBundleSize::Float64
    DMRS::DMRSType
    PTRS::PTRSType
    NumLayers::Float64
    MappingType::String
    SymbolAllocation::Vector{Float64}
    PRBSet::Matrix{Float64}
    RNTI::Float64
    EnablePTRS::Bool
    EnableCodewords::Float64
end

# 定义扩展参数结构体
struct Extension
    W::Array{ComplexF64, 3}  # 这里使用ComplexF64表示复数类型，根据你的实际情况可能需要调整精度
    PRGBundleSize::Float64
    TargetCodeRate::Float64
    XOverhead::Float64
end

function hMultiDLReceive(carrier, PDSCHs, rx, alg)
    
    numUEs = length(rx)
    TBS = Vector{Any}(undef, numUEs)
    CRC = Vector{Any}(undef, numUEs)
    eqSymbols = Vector{Any}(undef, numUEs)

    for ue in 1:numUEs
        # Extract the configuration for this UE
        pdsch = PDSCHs[ue].Config
        pdschExt = PDSCHs[ue].Extension

        # Perform OFDM demodulation (for ChannelFiltering = true)
        rxGrid = rx[ue].rxGrid
        offset = rx[ue].ChannelFilterDelay
        if isempty(rxGrid)
            rxWaveform = rx[ue].rxWaveform
            rxWaveform = rxWaveform[(1 + offset):end, :]
            rxGrid = nrOFDMDemodulate(carrier, rxWaveform)
        end

        # Perform channel and noise estimation
        if alg.PerfectChannelEstimator
            H = nrPerfectChannelEstimate(carrier, rx[ue].pathGains, rx[ue].pathFilters, offset, rx[ue].sampleTimes)
            nVarUE = rx[ue].noisePower
        else
            # Create DM - RS symbols and indices
            dmrsIndices = nrPDSCHDMRSIndices(carrier, pdsch)
            dmrsSymbols = nrPDSCHDMRS(carrier, pdsch)
            H, nVarUE = hSubbandChannelEstimate(carrier, rxGrid, dmrsIndices, dmrsSymbols, pdschExt.PRGBundleSize, CDMLengths=[2, 2])

            # Average noise estimate across PRGs and layers
            nVarUE = mean(nVarUE)
        end

        # Create PDSCH indices and extract allocated PDSCH REs in the
        # received grid and channel estimation
        pdschIndices, indicesInfo = nrPDSCHIndices(carrier, pdsch)
        pdschRx, pdschH, _, pdschHIndices = nrExtractResources(pdschIndices, rxGrid, H)

        # If perfect channel estimation is configured, the channel
        # estimates must be precoded so that they are w.r.t. layers rather
        # than transmit antennas
        if alg.PerfectChannelEstimator
            pdschH = nrPDSCHPrecode(carrier, pdschH, pdschHIndices, permutedims(pdschExt.W, [2, 1, 3]))
        end

        # Perform equalization
        eqSymbols[ue], csi = nrEqualizeMMSE(pdschRx, pdschH, nVarUE)

        # Perform PDSCH demodulation
        cws, rxSymbols = nrPDSCHDecode(carrier, pdsch, eqSymbols[ue], nVarUE)

        # Apply CSI to demodulated codewords
        csi = nrLayerDemap(csi)
        for c in 1:pdsch.NumCodewords
            Qm = length(cws[c]) ÷ length(rxSymbols[c])
            csi[c] = repeat(csi[c]', Qm, 1)
            cws[c] = cws[c] .* csi[c][:]
        end

        # Perform DL - SCH decoding
        decodeDLSCH = nrDLSCHDecoder()
        decodeDLSCH.TargetCodeRate = pdschExt.TargetCodeRate
        decodeDLSCH.LDPCDecodingAlgorithm = "Normalized min - sum"
        decodeDLSCH.MaximumLDPCIterationCount = 6
        TBS[ue] = nrTBS(pdsch.Modulation, pdsch.NumLayers, length(pdsch.PRBSet), indicesInfo.NREPerPRB, pdschExt.TargetCodeRate, pdschExt.XOverhead)
        decodeDLSCH.TransportBlockLength = TBS[ue]
        RV = 0
        _, CRC[ue] = decodeDLSCH(cws, pdsch.Modulation, pdsch.NumLayers, RV)
    end

    # Note that although this function supports practical channel / noise
    # estimation for PDSCH reception, the noise variance returned for each
    # UE is the true noise variance recorded in the received waveform
    # information. This is because the noise variance returned here may be
    # used in place of a CSI report, which would use a wideband CSI - RS.
    # This would result in a more accurate noise estimate than that
    # achievable using the PDSCH DM - RS with a limited PRB allocation
    nVar = [rx[i].noisePower for i in 1:length(rx)]

    return TBS, CRC, eqSymbols, nVar
end
